﻿using Clancy.Common;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls.Ribbon;
using Xceed.Wpf.AvalonDock.Layout;
using Xceed.Wpf.AvalonDock.Layout.Serialization;

namespace Clancy.Ui.Views
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private const string c_WindowLayoutFile = "layout.xml";

        public MainWindow()
        {
            InitializeComponent();
        }

        private void LinkHidingEventOfAnchorables(IEnumerable<ILayoutElement> children)
        {
            foreach (ILayoutElement child in children)
            {
                LayoutAnchorable anchorable = child as LayoutAnchorable;
                LayoutPanel layoutPanel = child as LayoutPanel;
                LayoutAnchorablePaneGroup layoutAnchorablePaneGroup = child as LayoutAnchorablePaneGroup;
                LayoutAnchorablePane layoutAnchorablePane = child as LayoutAnchorablePane;

                if (anchorable != null)
                {
                    anchorable.Hiding += OnHiding;
                    if (anchorable.IsHidden)
                    {
                        SetMenuItemRestoreWindow(anchorable);
                    }
                }

                if (layoutPanel != null)
                {
                    LinkHidingEventOfAnchorables(layoutPanel.Children);
                }
                else if (layoutAnchorablePaneGroup != null)
                {
                    LinkHidingEventOfAnchorables(layoutAnchorablePaneGroup.Children);
                }
                else if (layoutAnchorablePane != null)
                {
                    LinkHidingEventOfAnchorables(layoutAnchorablePane.Children);
                }
            }
        }

        private void OnHiding(object sender, CancelEventArgs e)
        {
            LayoutContent closedElement = sender as LayoutContent;
            if (closedElement == null)
                return;

            SetMenuItemRestoreWindow(closedElement);
        }

        private void OnMainWindowClosing(object sender, CancelEventArgs e)
        {
            if (MessageBox.Show(Properties.Resources.ReallyClose, Properties.Resources.Closing, MessageBoxButton.YesNo) == MessageBoxResult.No)
            {
                e.Cancel = true;
                return;
            }

            SaveWindowLayout();
        }

        private void OnMainWindowLoaded(object sender, RoutedEventArgs e)
        {
            if (!File.Exists(c_WindowLayoutFile))
                return;

            var serializer = new XmlLayoutSerializer(DockingManager);
            using (var stream = new StreamReader(c_WindowLayoutFile))
            {
                serializer.LayoutSerializationCallback += (s, args) =>
                {
                    args.Content = Application.Current.MainWindow.FindName(args.Model.ContentId);
                };
                serializer.Deserialize(stream);
            }

            RestoreMenusForAllHiddenItems();
        }

        private void OnWindowRestoreClicked(object sender, RoutedEventArgs e)
        {
            RibbonButton senderMenu = sender as RibbonButton;
            if (senderMenu == null)
                return;

            LayoutAnchorable closedElement = senderMenu.Tag as LayoutAnchorable;
            if (closedElement == null)
            {
                return;
            }

            closedElement.Show();

            RibbonApplicationMenu dependencyObject = senderMenu.Parent as RibbonApplicationMenu;
            if (dependencyObject != null)
            {
                dependencyObject.Items.Remove(senderMenu);
            }
        }

        private void RestoreMenusForAllHiddenItems()
        {
            ApplicationMenu.Items.Clear();

            LinkHidingEventOfAnchorables(DockingManager.Layout.Children);
        }

        private void SaveWindowLayout()
        {
            XmlLayoutSerializer serializer = new XmlLayoutSerializer(DockingManager);
            using (var stream = new StreamWriter(c_WindowLayoutFile))
            {
                serializer.Serialize(stream);
            }
        }

        private void SetMenuItemRestoreWindow(LayoutContent closedElement)
        {
            RibbonButton newItem = new RibbonButton
            {
                LargeImageSource = Properties.Resources.window_new_8.ToImageSource(),
                Label = closedElement.Title,
                Tag = closedElement,
                CommandParameter = closedElement
            };
            newItem.Click += OnWindowRestoreClicked;

            ApplicationMenu.Items.Add(newItem);
        }
    }
}